﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class ForceParam
{
    public enum InputType
    {
        None = 0,
        Up,
        Down,
        Left,
        Right,
    };
    
    [System.Serializable]
    public class InputForceParam {
        public float forceScaleUp, forceScaleDown,
        forceScaleLeft, forceScaleRight, forceDefault;
        public float forceForward;

        public Vector2 GetInputForce(InputType type)
        {
            switch (type)
            {
                case InputType.None: return new Vector2(0, -forceDefault);
                case InputType.Up: return new Vector2(0, forceScaleUp);
                case InputType.Down: return new Vector2(0, -forceScaleDown);
                case InputType.Left: return new Vector2(-forceScaleLeft, 0);
                case InputType.Right: return new Vector2(forceScaleRight, 0);
            }

            return new Vector2(0, 0);
        }

        public Vector2 GetForwardForce()
        {
            return new Vector2(forceForward, 0);
        }

        public List<List<string>> DumpParams()
        {
            var paramDict = new SortedDictionary<string, float>()
            {
                { "forceScaleUp", forceScaleUp },
                { "forceScaleDown", forceScaleDown },
                { "forceScaleLeft", forceScaleLeft },
                { "forceScaleRight", forceScaleRight },
                { "forceDefault", forceDefault },
                { "forceForward", forceForward }
            };
            var ret = new List<List<string>>();
            foreach (var item in paramDict)
            {
                var ele = new List<string>()
                {
                    item.Key, item.Value.ToString()
                };

                ret.Add(ele);
            }
            return ret;
        }
        public void LoadParams(List<List<string>> param)
        {
            foreach (var i in param)
            {
                if (i[0] == "forceScaleUp") forceScaleUp = float.Parse(i[1]);
                if (i[0] == "forceScaleDown") forceScaleDown = float.Parse(i[1]);
                if (i[0] == "forceScaleLeft") forceScaleLeft = float.Parse(i[1]);
                if (i[0] == "forceScaleRight") forceScaleRight = float.Parse(i[1]);
                if (i[0] == "forceDefault") forceDefault = float.Parse(i[1]);
                if (i[0] == "forceForward") forceForward = float.Parse(i[1]);
            }
        }
    }
    public InputForceParam inputForceParam;

    [System.Serializable]
    public class ForceFieldParam
    {
        public float fieldMagnitude, fieldAngle;
        public Vector2 GetFieldForce()
        {
            return new Vector2(fieldMagnitude * Mathf.Cos(fieldAngle),
                    fieldMagnitude * Mathf.Sin(fieldAngle));
        }

        public List<List<string>> DumpParams()
        {
            var paramDict = new SortedDictionary<string, float>()
            {
                { "forceMagnitude", fieldMagnitude },
                { "forceAngle", fieldAngle },
            };
            var ret = new List<List<string>>();
            foreach (var item in paramDict)
            {
                var ele = new List<string>()
                {
                    item.Key, item.Value.ToString()
                };

                ret.Add(ele);
            }
            return ret;
        }

        public void LoadParams(List<List<string>> param)
        {
            foreach (var i in param)
            {
                if (i[0] == "forceMagnitude") fieldMagnitude = float.Parse(i[1]);
                if (i[0] == "forceAngle") fieldAngle = float.Parse(i[1]);
            }
        }
    }
    public ForceFieldParam forceFieldParam;

    public List<List<string>> DumpParams()
    {
        var ret = new List<List<string>>();
        ret.Add(new List<string>() { "inputForceParam" });
        var param = inputForceParam.DumpParams();
        ret.AddRange(param);
        ret.Add(new List<string>() { "forceFieldParam" });
        param = forceFieldParam.DumpParams();
        ret.AddRange(param);
        return ret;
    }
    public void LoadParams(List<List<string>> param)
    {
        for (int i = 0; i < param.Count; i++)
        {
            var x = param[i];
            if (x[0] == "inputForceParam")
            {
                inputForceParam.LoadParams(param.GetRange(i + 1, 6));
                i += 6;
                continue;
            }
            if (x[0] == "forceFieldParam")
            {
                forceFieldParam.LoadParams(param.GetRange(i + 1, 2));
                i += 2;
                continue;
            }
        }
    }

}

public class ParameterManager : MonoBehaviour
{
    public ForceParam normalParam, lightParam, heavyParam;
    

    public static ParameterManager manager;

    private void Awake()
    {
        manager = this;
    }

    public static ForceParam GetParamOfState(Head.State state)
    {
        switch (state)
        {
            case Head.State.Heavy: return manager.heavyParam;
            case Head.State.Light: return manager.lightParam;
            case Head.State.Normal: return manager.normalParam;
        }
        return manager.normalParam;
    }

    public static Vector2 GetInputForce(Head head, ForceParam.InputType type)
    {
        var activeParam = GetParamOfState(head.state);
        return activeParam.inputForceParam.GetInputForce(type);
    }

    public static Vector2 GetFieldForce(Head head)
    {
        var activeParam = GetParamOfState(head.state);
        return activeParam.forceFieldParam.GetFieldForce();
    }

    public static Vector2 GetForwardForce(Head head)
    {
        var activeParam = GetParamOfState(head.state);
        return activeParam.inputForceParam.GetForwardForce();
    }

    public List<List<string>> DumpParams()
    {
        var paramDict = new SortedDictionary<string, ForceParam>()
            {
                { "normalParam", normalParam },
                { "lightParam", lightParam },
                { "heavyParam", heavyParam }
            };
        var ret = new List<List<string>>();
        foreach (var item in paramDict)
        {
            ret.Add(new List<string>() { item.Key });
            var param = item.Value.DumpParams();
            ret.AddRange(param);
        }
        return ret;
    }
    public void LoadParams(List<List<string>> param)
    {
        for (int i = 0; i < param.Count; i++)
        {
            var x = param[i];
            if (x[0] == "normalParam")
            {
                normalParam.LoadParams(param.GetRange(i + 1, 10));
                i += 10;
                continue;
            }
            if (x[0] == "lightParam")
            {
                lightParam.LoadParams(param.GetRange(i + 1, 10));
                i += 10;
                continue;
            }
            if (x[0] == "heavyParam")
            {
                heavyParam.LoadParams(param.GetRange(i + 1, 10));
                i += 10;
                continue;
            }
        }
    }

}
